package com.miwzn.boot.modules.sys.web;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.miwzn.boot.component.service.ShiroService;
import com.miwzn.boot.modules.form.LoginForm;
import com.miwzn.base.TokenEntity;
import com.miwzn.boot.component.config.shiro.ShiroUser;
import com.miwzn.boot.modules.sys.entity.dto.SysMenuDto;
import com.miwzn.boot.modules.sys.entity.dto.SysUserDto;
import com.miwzn.boot.modules.sys.entity.po.SysMenu;
import com.miwzn.boot.modules.sys.entity.po.SysUser;
import com.miwzn.boot.modules.sys.entity.qm.SysMenuQuery;
import com.miwzn.boot.modules.sys.service.SysMenuService;
import com.miwzn.boot.modules.sys.service.SysUserService;
import com.miwzn.comm.ResponseEntity;
import com.miwzn.comm.annotation.OperationLog;
import com.miwzn.comm.constant.MyConstant;
import com.miwzn.comm.exception.BsRException;
import com.miwzn.comm.utils.*;
import com.miwzn.comm.utils.validate.ValidatorUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: wzn
 * @Date: 2018/6/19 14:27
 * @Description:
 */
@Controller
public class CommController {

    @Autowired
    private Producer producer;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private ShiroService shiroService;

    @ResponseBody
    @RequiresUser
    @GetMapping("/check/permissions")
    protected ResponseEntity checkPermissions(String codes) {

        Map<String, Boolean> map = new HashMap<>();
        if (StringUtils.isNotBlank(codes)) {
            for (String s : codes.split(",")) {
                try {
                    Subject currentUser = SecurityUtils.getSubject();
                    currentUser.checkPermission(s);
                    map.put(s.replaceAll(":", ""), true);
                } catch (AuthorizationException var3) {
                    map.put(s.replaceAll(":", ""), false);
                }
            }
        }
        return new ResponseEntity().put("data", map);
    }


    @GetMapping("captcha.jpg")
    public void captcha(HttpServletResponse response) throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //生成文字验证码
        String text = producer.createText();
        //生成图片验证码
        BufferedImage image = producer.createImage(text);
        //保存到shiro session
        ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
    }

    /**
     * 登录方法
     *
     * @param loginForm
     *
     * @return
     */
    @OperationLog(operation = "系统-登录", content = "用户登录")
    @ResponseBody
    @PostMapping("/sys/login")
    public ResponseEntity login(@RequestBody LoginForm loginForm) {
        ValidatorUtils.validateEntity(loginForm);
//        String kaptcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY);
//        if (!captcha.equalsIgnoreCase(kaptcha)) {
//            // return Result.error("验证码不正确");
//        }
        try {
            Subject subject = ShiroUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(loginForm.getUsername(), loginForm.getPassword());
            subject.login(token);
        } catch (UnknownAccountException e) {
            return ResponseEntity.error(e.getMessage());
        } catch (IncorrectCredentialsException e) {
            throw new BsRException("账号或密码不正确");
        } catch (LockedAccountException e) {
            throw new BsRException("账号已被锁定,请联系管理员");
        } catch (AuthenticationException e) {
            throw new BsRException("账户验证失败");
        }

        return new ResponseEntity().put("data", new TokenEntity(ShiroUtils.getSession().getId().toString()));
    }


    /**
     * 注册方法
     *
     * @param entity
     *
     * @return
     */
    @OperationLog(operation = "系统-注册", content = "用户注册")
    @ResponseBody
    @PostMapping("/sys/register")
    public ResponseEntity register(@RequestBody SysUser entity) {
        if (StringUtils.isBlank(entity.getMobile())) throw new BsRException("手机号不能为空");
        final PasswordEntity p = PasswordUtil.getPassword(entity.getPassword());
        entity.setPassword(p.getPassword());
        entity.setSalt(p.getSalt());
        sysUserService.insertD(entity);
        return ResponseEntity.success().put("data", entity);
    }


    /**
     * 获取导航菜单
     *
     * @return
     */
    @OperationLog(operation = "系统-导航", content = "获取导航菜单")
    @ResponseBody
    @GetMapping("/sys/menu/nav")
    public ResponseEntity nav() {
        List<SysMenu> list = sysMenuService.selectNav();
        return ResponseEntity.success().put("data", list);
    }


    /**
     * PC注册方法
     *
     * @param entity
     *
     * @return
     */
    @OperationLog(operation = "系统-注册", content = "PC注册方法")
    @ResponseBody
    @PostMapping("/sys/pc/register")
    public ResponseEntity pcRegister(@RequestBody SysUserDto entity) {
        if (StringUtils.isBlank(entity.getMobile())) throw new BsRException("手机号不能为空");

        SysUser q = new SysUser();
        q.setUsername(entity.getUsername());
        q.setDelFlag(MyConstant.FLAG_N);
        final List<SysUser> select = sysUserService.select(q);
        if (CollectionUtils.isNotEmpty(select)) {
            throw new BsRException("用户名已经存在");
        }
        SysUser user = new SysUser();
        BeanUtils.copyProperties(entity, user);
        String password = user.getMobile().substring(entity.getMobile().length() - 6);
        final PasswordEntity p = PasswordUtil.getPassword(password);
        user.setPassword(p.getPassword());
        user.setSalt(p.getSalt());
        sysUserService.insert(user);
        entity.setId(user.getId());
        return ResponseEntity.success("添加成功").put("data", entity);
    }

    /**
     * 获取当前登录用户
     *
     * @return
     */
    @OperationLog(operation = "系统-用户", content = "获取当前登录用户")
    @ResponseBody
    @GetMapping("/sys/user/info")
    public ResponseEntity userInfo() {
        final ShiroUser loginUser = CommUtil.getLoginUser();
        return ResponseEntity.success().put("data", loginUser);
    }


    /**
     * 更新当前登录用户角色
     *
     * @return
     */
    @OperationLog(operation = "系统-用户", content = "更新当前登录用户角色")
    @ResponseBody
    @PostMapping("/sys/user/role/change")
    public ResponseEntity roleChange(@RequestParam(value = "roleId", required = true) String roleId) {
        ShiroUser shiroUser = shiroService.updateShiroUser(roleId);
        return ResponseEntity.success().put("data", shiroUser);
    }

    /**
     * 密码修改
     *
     * @param password
     * @param newPassword
     *
     * @return
     */
    @OperationLog(operation = "系统-用户", content = "密码修改")
    @ResponseBody
    @PostMapping("/sys/user/password")
    public ResponseEntity updatePassword(String password, String newPassword) {
        if (StringUtils.isBlank(password) || StringUtils.isBlank(newPassword)) {
            return ResponseEntity.error("密码不能为空");
        }
        final ShiroUser loginUser = CommUtil.getLoginUser();
        final PasswordEntity password1 = PasswordUtil.getPassword(password, loginUser.getSalt());
        if (!loginUser.getPassword().equals(password1.getPassword())) {
            return ResponseEntity.error("原密码不正确");
        }
        SysUser u = new SysUser();
        final PasswordEntity password2 = PasswordUtil.getPassword(newPassword);
        u.setId(loginUser.getId());
        u.setPassword(password2.getPassword());
        u.setSalt(password2.getSalt());
        sysUserService.updateByPrimaryKeySelective(u);
        return ResponseEntity.success();
    }


    /**
     * 登出方法
     *
     * @return
     */
    @OperationLog(operation = "系统-登出", content = "退出登录")
    @GetMapping("/sys/logout")
    public String logout() {
        ShiroUtils.logout();
        return "redirect:login.html";
    }
}
